#ifndef __ASYNC_H__
#define __ASYNC_H__

#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>

// 前向声明
typedef void* (*routine_t)(void*);

// 异步任务结果结构体
typedef struct {
    void* result;           // 任务执行结果
    bool completed;         // 任务是否已完成
#ifdef _WIN32
    HANDLE completion_event;// 用于等待的事件句柄
#else
    pthread_cond_t cond;    // 条件变量，用于等待任务完成
    pthread_mutex_t mutex;  // 互斥锁，保护条件变量
#endif
} async_result_t;

// 包装后的任务函数，用于捕获结果
typedef struct {
    routine_t func;         // 实际要执行的函数
    void* args;             // 函数参数
    async_result_t* result; // 结果存储
} async_task_t;

/* 函数声明 */

// 初始化异步框架
void async_init(void);

// 提交异步任务
async_result_t* async(routine_t routine, void* args);

// 等待异步任务完成并获取结果
void* await(async_result_t* result);

// 非阻塞尝试获取任务结果，如果未完成则返回NULL
void* async_try_await(async_result_t* result);

// 等待所有异步任务完成并清理资源
void async_cleanup(void);

#endif // __ASYNC_H__

#ifdef ASYNC_IMPLEMENTATION

// 线程池实例
static tpool_t* async_pool = NULL;

// 包装任务执行函数，用于捕获返回结果
static void* async_wrapper(void* args) {
    async_task_t* task = (async_task_t*)args;
    
    // 执行实际任务并保存结果
    task->result->result = task->func(task->args);
    
    // 标记任务完成
#ifdef _WIN32
    // Windows: 触发事件
    task->result->completed = true;
    SetEvent(task->result->completion_event);
#else
    // POSIX: 通知条件变量
    pthread_mutex_lock(&task->result->mutex);
    task->result->completed = true;
    pthread_cond_signal(&task->result->cond);
    pthread_mutex_unlock(&task->result->mutex);
#endif
    
    // 清理任务包装器
    free(task);
    return NULL;
}

/**
 * @brief 初始化异步框架，创建线程池
 * 线程数量基于系统CPU核心数确定
 */
void async_init(void) {
    if (async_pool != NULL) return; // 已初始化
    
    async_pool = (tpool_t*)malloc(sizeof(tpool_t));
    if (!async_pool) {
        fprintf(stderr, "内存分配失败: async_pool\n");
        return;
    }
    
    // 获取CPU核心数
#ifdef _WIN32
    SYSTEM_INFO sysinfo;
    GetSystemInfo(&sysinfo);
    uint8_t n = sysinfo.dwNumberOfProcessors;
#else
    uint8_t n = (uint8_t)sysconf(_SC_NPROCESSORS_ONLN);
#endif
    
    // 留一个核心给主线程
    if (n > 1) {
        n--;
    }
    
    // 初始化线程池
    tpool_new(async_pool, n);
}

/**
 * @brief 提交异步任务
 * @param routine 要异步执行的函数
 * @param args 传递给函数的参数
 * @return 异步任务结果的指针，可用于await
 */
async_result_t* async(routine_t routine, void* args) {
    if (!async_pool) {
        fprintf(stderr, "请先调用async_init()初始化\n");
        return NULL;
    }
    
    // 创建结果结构体
    async_result_t* result = (async_result_t*)malloc(sizeof(async_result_t));
    if (!result) {
        fprintf(stderr, "内存分配失败: async_result_t\n");
        return NULL;
    }
    
    // 初始化结果结构体
    result->result = NULL;
    result->completed = false;
    
#ifdef _WIN32
    // Windows: 创建事件
    result->completion_event = CreateEvent(
        NULL,               // 默认安全属性
        TRUE,               // 手动重置事件
        FALSE,              // 初始状态为未触发
        NULL                // 无名称
    );
    if (result->completion_event == NULL) {
        fprintf(stderr, "创建事件失败\n");
        free(result);
        return NULL;
    }
#else
    // POSIX: 初始化条件变量和互斥锁
    pthread_mutex_init(&result->mutex, NULL);
    pthread_cond_init(&result->cond, NULL);
#endif
    
    // 创建任务包装器
    async_task_t* task = (async_task_t*)malloc(sizeof(async_task_t));
    if (!task) {
        fprintf(stderr, "内存分配失败: async_task_t\n");
#ifdef _WIN32
        CloseHandle(result->completion_event);
#else
        pthread_mutex_destroy(&result->mutex);
        pthread_cond_destroy(&result->cond);
#endif
        free(result);
        return NULL;
    }
    
    task->func = routine;
    task->args = args;
    task->result = result;
    
    // 提交任务到线程池
    tpool_push(async_pool, async_wrapper, task);
    
    return result;
}

/**
 * @brief 等待异步任务完成并获取结果
 * @param result 异步任务结果指针（由async()返回）
 * @return 任务执行的返回值
 */
void* await(async_result_t* result) {
    if (!result) return NULL;
    
    // 等待任务完成
#ifdef _WIN32
    // Windows: 等待事件触发
    WaitForSingleObject(result->completion_event, INFINITE);
#else
    // POSIX: 等待条件变量
    pthread_mutex_lock(&result->mutex);
    while (!result->completed) {
        pthread_cond_wait(&result->cond, &result->mutex);
    }
    pthread_mutex_unlock(&result->mutex);
#endif
    
    // 保存结果并清理
    void* res = result->result;
    
#ifdef _WIN32
    CloseHandle(result->completion_event);
#else
    pthread_mutex_destroy(&result->mutex);
    pthread_cond_destroy(&result->cond);
#endif
    free(result);
    
    return res;
}

/**
 * @brief 非阻塞尝试获取任务结果
 * @param result 异步任务结果指针
 * @return 如果任务已完成，返回任务结果；否则返回NULL
 * @note 此函数不会阻塞等待，调用后需要检查返回值是否为NULL
 */
void* async_try_await(async_result_t* result) {
    if (!result) return NULL;
    
    // 检查任务是否已完成
#ifdef _WIN32
    // Windows: 检查事件状态
    if (WaitForSingleObject(result->completion_event, 0) == WAIT_OBJECT_0) {
        // 任务已完成，返回结果并清理
        void* res = result->result;
        CloseHandle(result->completion_event);
        free(result);
        return res;
    }
#else
    // POSIX: 检查完成标志
    pthread_mutex_lock(&result->mutex);
    if (result->completed) {
        // 任务已完成，返回结果并清理
        void* res = result->result;
        pthread_mutex_unlock(&result->mutex);
        pthread_mutex_destroy(&result->mutex);
        pthread_cond_destroy(&result->cond);
        free(result);
        return res;
    }
    pthread_mutex_unlock(&result->mutex);
#endif
    
    // 任务未完成
    return NULL;
}

/**
 * @brief 等待所有异步任务完成并清理资源
 */
void async_cleanup(void) {
    if (async_pool) {
        tpool_finish(async_pool);
        free(async_pool);
        async_pool = NULL;
    }
}

#endif // ASYNC_IMPLEMENTATION
